package com.xueyi.aixihu.service.impl;

import cn.hutool.core.date.DateUtil;
import com.xueyi.aixihu.constant.*;
import com.xueyi.aixihu.entity.generatedMapper.AxhFinanceDao;
import com.xueyi.aixihu.entity.po.*;
import com.xueyi.aixihu.entity.vo.*;
import com.xueyi.aixihu.exception.SzException;
import com.xueyi.aixihu.mapper.ReportFormsMapper;
import com.xueyi.aixihu.reqeust.FindReportFormListReq;
import com.xueyi.aixihu.reqeust.PublishReportFormReq;
import com.xueyi.aixihu.reqeust.UploadReportFormsReq;
import com.xueyi.aixihu.reqeust.UploadVoucherReq;
import com.xueyi.aixihu.response.UploadImageResponse;
import com.xueyi.aixihu.service.ReportFormsService;
import com.xueyi.aixihu.status.IsStatus;
import com.xueyi.aixihu.status.SystemCode;
import com.xueyi.aixihu.utils.AliYunOSSUtil;
import com.xueyi.aixihu.utils.OfficeConvertUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author hxs
 * @createDate 2023/6/28 11:40
 * @description 上传报表相关接口
 */
@Service
public class ReportFormsServiceImpl implements ReportFormsService {

    @Resource(type = ReportFormsMapper.class)
    private ReportFormsMapper reportFormsMapper;

    @Resource(type = OfficeConvertUtil.class)
    private OfficeConvertUtil officeConvertUtil;

    @Resource(type = AxhFinanceDao.class)
    private AxhFinanceDao axhFinanceDao;

    /**
     * 上传报表
     */
    @Override
    public void uploadReportForms(UploadReportFormsReq uploadReportFormsReq) throws IOException, SzException {

        DtUsersVo user = DtUsersVo.findCurrentUser();

//        if (!ThreeAssetConstant.CW.equals(uploadReportFormsReq.getReportType())) {
//            uploadReportFormsReq.setSystemTypeId(-1);
//        } else {
//            uploadReportFormsReq.setSystemTypeId(0);
//        }

        if (uploadReportFormsReq.getSystemTypeId() == null) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "请选择报表类型");
        }

        //获取当前登录用户的角色
        Integer userMaxRole = user.getUserMaxRole();
        Integer role = userMaxRole;
        Integer areaType = findAreaType(role);
        if (areaType.equals(-1)) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
        }

        String areaId = "";

        if (SystemRoleConstant.CUN.equals(role)) {
            areaId = user.findUserManageAreaId();
        } else if (SystemRoleConstant.SQ.equals(role)) {
            areaId = user.findUserManageCommunityId();
        } else if (SystemRoleConstant.JU_WEI.equals(role)) {
            areaId = user.findUserManageJuWeiId();
        } else if (SystemRoleConstant.Z_CZS_CY.equals(role)) {
            areaId = user.findUserManageTownId();
        } else {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
        }

        if (!StringUtils.hasLength(areaId) || "-111".equals(areaId)) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
        }

        MultipartFile file = uploadReportFormsReq.getFile();
        //文件转图片
        String img = "不用PDF转图片了"; //officeConvertUtil.convertOfficeToImg(file.getInputStream());

        //封装对象
        AxhFinanceVo flag = new AxhFinanceVo();
        if (!StringUtils.hasLength(uploadReportFormsReq.getTitle())) {
            String oneTitle = DateUtil.format(new Date(), "yyyy年MM月");
            // 查询自己管理的地址
            List<DtNewsSort> userManageArea = null;

            if (userMaxRole.equals(SystemRoleConstant.CUN)) {
                userManageArea = user.findUserManageArea();
            } else if (userMaxRole.equals(SystemRoleConstant.SQ)) {
                userManageArea = user.findUserManageCommunity();
            } else if (userMaxRole.equals(SystemRoleConstant.Z_CZS_CY)) {
                userManageArea = user.findUserManageTown();
            } else if (userMaxRole.equals(SystemRoleConstant.JU_WEI)) {
                userManageArea = user.findUserManageJuWei();
            }


            if (CollectionUtils.isEmpty(userManageArea)) {
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "查询用户管理的地址失败");
            }
            DtNewsSort dtNewsSort = userManageArea.get(0);
            String reportTypeStr = uploadReportFormsReq.getReportType().equals(ThreeAssetConstant.ZJ) ? "资金" :
                    uploadReportFormsReq.getReportType().equals(ThreeAssetConstant.ZC) ? "资产" :
                            uploadReportFormsReq.getReportType().equals(ThreeAssetConstant.ZY) ? "资源" : "财务";
            uploadReportFormsReq.setTitle(oneTitle.concat(dtNewsSort.getName()).concat(reportTypeStr).concat("报表"));
        }
        flag.setFinanceTitle(uploadReportFormsReq.getTitle());
        flag.setCurrentStatus(OneLevelAuditConstant.DRAFT);
        flag.setCreateUserId(user.getId());
        flag.setAreaType(areaType);
        flag.setReportImages(img);
        flag.setReportType(uploadReportFormsReq.getReportType());
        flag.setSystemTypeId(uploadReportFormsReq.getSystemTypeId());

        String[] tem = areaId.split(",");
        flag.setFromToAreaId(Integer.parseInt(tem[0]));

        if (uploadReportFormsReq.getId() == null) {
            String sourceFileUrl = AliYunOSSUtil.upload(file, UploadImageResponse.UploadImageStatus.SZ_IV);
            flag.setSourceFileUrl(sourceFileUrl);
            reportFormsMapper.saveReportForms(flag);

        } else {
            flag.setId(uploadReportFormsReq.getId());
            try {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                flag.setLastUpdateTime(simpleDateFormat.parse(uploadReportFormsReq.getDateTime()));
                flag.setCreateTime(simpleDateFormat.parse(uploadReportFormsReq.getDateTime()));
                flag.setReportProofImage(uploadReportFormsReq.getReportProofImage());
                reportFormsMapper.updateReportForms(flag);
            } catch (Exception e) {
                e.printStackTrace();
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "修改失败");
            }
        }
    }

    /**
     * 查询地区列表
     */
    @Override
    public List<DtNewsSort> findAddressList() {
        DtUsersVo user = DtUsersVo.findCurrentUser();
        Integer userMaxRole = user.findUserMaxRole();
        //镇财政所成员
        if (SystemRoleConstant.Z_CZS_CY.equals(userMaxRole)) {
            return user.findUserManageTown();
        }
        //居委会、社区
        else if (SystemRoleConstant.SQ.equals(userMaxRole)) {
            return user.findUserManageCommunity();
        }
        //村
        else if (SystemRoleConstant.CUN.equals(userMaxRole)) {
            return user.findUserManageArea();
        }
        return null;
    }

    /**
     * 查询报表列表
     *
     * @param findReportFormListReq 查询参数
     * @return 列表
     */
    @Override
    public DataList<AxhFinanceVo> findReportFormList(FindReportFormListReq findReportFormListReq) throws SzException {
        findReportFormListReq.format();
        DtUsersVo user = DtUsersVo.findCurrentUser();

        Integer reportType = findReportFormListReq.getReportType();
        Integer role = user.getUserMaxRole();

        String areaIds = "";

        //村、社区 才有查询三资列表权限
        if (ThreeAssetConstant.ZJ.equals(reportType) || ThreeAssetConstant.ZY.equals(reportType) || ThreeAssetConstant.ZC.equals(reportType)) {
            if (!(SystemRoleConstant.CUN.equals(role) || SystemRoleConstant.SQ.equals(role) || SystemRoleConstant.JU_WEI.equals(role))) {
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
            }
            areaIds = SystemRoleConstant.CUN.equals(role) ? user.findUserManageAreaId() : SystemRoleConstant.SQ.equals(role) ? user.findUserManageCommunityId() :
                    user.findUserManageJuWeiId();
        }
        //财务
        else if (ThreeAssetConstant.CW.equals(reportType)) {
            if (!(SystemRoleConstant.CUN.equals(role) || SystemRoleConstant.JU_WEI.equals(role) || SystemRoleConstant.SQ.equals(role) || SystemRoleConstant.Z_CZS_CY.equals(role) || SystemRoleConstant.Z_CZS_SZ.equals(role))) {
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
            }
            areaIds = (SystemRoleConstant.Z_CZS_CY.equals(role) || SystemRoleConstant.Z_CZS_SZ.equals(role)) ? user.findUserManageTownId() : SystemRoleConstant.SQ.equals(role) ? user.findUserManageCommunityId() :
                    SystemRoleConstant.JU_WEI.equals(role) ? user.findUserManageJuWeiId() :
                            user.findUserManageAreaId();
        } else {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
        }

        if (!StringUtils.hasLength(areaIds)) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
        }

        findReportFormListReq.setCurrentStatusStr(checkCurrentStatusStr(findReportFormListReq.getCurrentStatus(), role));

        Integer total = reportFormsMapper.findReportFormListTotal(findReportFormListReq, user.getId(), areaIds);
        List<AxhFinanceVo> list = new ArrayList<>();
        if (total > 0) {
            list = reportFormsMapper.findReportFormList(findReportFormListReq, user.getId(), areaIds);
        }

        if (!CollectionUtils.isEmpty(list)) {
            for (AxhFinanceVo item : list) {

                item.setFinanceStatusStr("1".equals(item.getIsPublic() + "") ? "已公开" : TwoLevelAuditConstant.findPlanStr(item.getCurrentStatus()));
            }
        }

        return new DataList<AxhFinanceVo>(list, total);
    }


    /**
     * 删除报表
     *
     * @param id 报表id
     */
    @Override
    public void deleteReportForm(Integer id) throws SzException {
        if (null == id || id < 1) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "参数异常");
        }
        AxhFinanceVo financeVo = reportFormsMapper.findReportFormById(id);
        if (null == financeVo) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "未查询到该报表~~~");
        }

        DtUsersVo user = DtUsersVo.findCurrentUser();

        //判断报表是否允许删除
        if (!checkIsAllowDeleteReportForm(financeVo, user)) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
        }

        reportFormsMapper.deleteReportForm(id);

    }

    /**
     * 发起审核
     *
     * @param id 报表id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void initiateAudit(Integer id) throws SzException {
        if (null == id || id < 1) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "参数异常");
        }
        AxhFinanceVo financeVo = reportFormsMapper.findReportFormById(id);
        if (null == financeVo) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "未查询到该报表~~~");
        }
        DtUsersVo user = DtUsersVo.findCurrentUser();

        Integer userMaxRole = user.getUserMaxRole();

        Integer currentStatus = financeVo.getCurrentStatus();

        Integer reportType = financeVo.getReportType();

        Integer areaType = financeVo.getAreaType();

        //只有一级审核 由镇财政所成员发起
//        if (ThreeAssetConstant.CW.equals(reportType)) {
        //镇级
        if (AddressConstant.ZJ.equals(areaType)) {
            if (!(OneLevelAuditConstant.DRAFT.equals(currentStatus) || OneLevelAuditConstant.FAIL.equals(currentStatus))) {
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "审核中~~~");
            }
            //角色是否为镇财政所成员 且是否是本人操作
            if (!(SystemRoleConstant.Z_CZS_CY.equals(userMaxRole) && user.getId().equals(financeVo.getCreateUserId()))) {
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
            }
            financeVo.setCurrentStatus(OneLevelAuditConstant.SUBMIT_AUDIT);
        } else {
            if (TwoLevelAuditConstant.DRAFT.equals(currentStatus) || TwoLevelAuditConstant.ONE_FAIL.equals(currentStatus)) {
                if (!((SystemRoleConstant.JU_WEI.equals(userMaxRole) || (SystemRoleConstant.CUN.equals(userMaxRole) || SystemRoleConstant.SQ.equals(userMaxRole)) && user.getId().equals(financeVo.getCreateUserId())))) {
                    throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
                }
                financeVo.setCurrentStatus(TwoLevelAuditConstant.SUBMIT_AUDIT);
            } else {
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "审核中~~~");
            }
        }


//        }
//        //有二级审核
//        else {
//            //草稿，由村、社区、居委会发起审核
//            if (TwoLevelAuditConstant.DRAFT.equals(currentStatus)) {
//                if (!((SystemRoleConstant.CUN.equals(userMaxRole) || SystemRoleConstant.SQ.equals(userMaxRole)) && user.getId().equals(financeVo.getCreateUserId()))) {
//                    throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
//                }
//                financeVo.setCurrentStatus(TwoLevelAuditConstant.SUBMIT_AUDIT);
//            } else {
//                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "审核中~~~");
//            }
//
//        }


        //修改报表审核状态
        reportFormsMapper.updateReportFormsAuditStatus(financeVo);

        CdzAuditRecord record = reportFormsMapper.findAuditRecord(financeVo.getId(), financeVo.getReportType());

        if (null == record) {
            record = new CdzAuditRecord();
            record.setAuditType(financeVo.getReportType());
            record.setJoinId(financeVo.getId());
            record.setSubmitUserId(user.getId());
            record.setCurrentStatus(financeVo.getCurrentStatus());
            reportFormsMapper.addReportFormsAuditRecord(record);
        } else {
            record.setSubmitUserId(user.getId());
            record.setCurrentStatus(financeVo.getCurrentStatus());
            reportFormsMapper.updateReportFormsAuditRecord(record);
        }


        //添加日志
        AxhFinanceLogVo axhFinanceLog = new AxhFinanceLogVo();
        axhFinanceLog.setFinanceId(financeVo.getId());
        axhFinanceLog.setCommandUserId(user.getId());
        axhFinanceLog.setLogContent("【报表审核】用户 " + user.getUsername() + " 提交了报表 《" + financeVo.getFinanceTitle() + "》 审核");
        axhFinanceLog.setCurrentFinanceStatus(FinanceAuditLogStep.SEND_AUDIT.VAL);
        reportFormsMapper.addFinanceLog(axhFinanceLog);


    }

    /**
     * 公开报表
     *
     * @param publishReportFormReq 审核记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishReportForm(PublishReportFormReq publishReportFormReq) throws SzException {


        AxhFinancePo axhFinancePo = axhFinanceDao.selectByPrimaryKey(publishReportFormReq.getId());
        if (null == axhFinancePo) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "未查询到该报表~~~");
        }

        //是否通过审核
        Integer currentStatus = axhFinancePo.getCurrentStatus();

        DtUsersVo user = DtUsersVo.findCurrentUser();
        Integer role = user.getUserMaxRole();

        //===========判断是否审核通过
        //镇财政所所长
        if (AddressConstant.ZJ.equals(axhFinancePo.getAreaType())) {
            if (!OneLevelAuditConstant.CONSENT.equals(currentStatus)) {
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "该报表未审核通过~~~");
            }
            // 需要镇财政所所长才能发布
            if (!role.equals(SystemRoleConstant.Z_CZS_SZ)) {
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "您当前不能进行公开操作");
            }
        }
        //居委会、社区、村
        else {
            if (!TwoLevelAuditConstant.TWO_CONSENT.equals(currentStatus)) {
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "该报表未审核通过~~~");
            }
            if (!axhFinancePo.getCreateUserId().equals(user.getId())) {
                throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
            }
        }

        axhFinancePo.setIsPublic(publishReportFormReq.getIsPublic());

        //修改报表
        reportFormsMapper.updateReportFromIsPublic(axhFinancePo.getId(), publishReportFormReq.getIsPublic());


        //日志
        AxhFinanceLogVo log = new AxhFinanceLogVo();
        log.setFinanceId(axhFinancePo.getId());
        log.setCommandUserId(user.getId());
        String msg = "【发布报表】用户 " + user.getUsername() + " " + ((IsStatus.YES.equals(publishReportFormReq.getIsPublic()) ? "发布" : "下架" + "了报表 《") + axhFinancePo.getFinanceTitle() + "》");
        log.setLogContent(msg);
        log.setCurrentFinanceStatus(FinanceAuditLogStep.PUBLIC.VAL);
        log.setRemark(IsStatus.YES.equals(axhFinancePo.getIsPublic()) ? "发布" : "取消发布");

        reportFormsMapper.addFinanceLog(log);


    }

    /**
     * 查询财务报表类型列表
     *
     * @param addressType
     * @return 财务报表类型列表
     */
    @Override
    public List<BaseSelectVo> findCwTypeList(Integer addressType) throws SzException {
        if (null == addressType) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "参数异常");
        }
        return reportFormsMapper.findCwTypeList((addressType.equals(1) ? 1 : 2), (addressType.equals(1) ? 3 : 6));
    }

    /**
     * 获取财务公开各种状态报表的数量
     *
     * @param reportType
     * @return 对象
     */
    @Override
    public FindReportFormsSizeVo findReportFormsSize(Integer reportType) throws SzException {
        if (null == reportType) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "参数异常");
        }
        DtUsersVo user = DtUsersVo.findCurrentUser();
        Integer role = user.getUserMaxRole();

        FindReportFormsSizeVo flag = new FindReportFormsSizeVo();

        String areaIds = "";


        if (SystemRoleConstant.CUN.equals(role)) {
            areaIds = user.findUserManageAreaId();

        } else if (SystemRoleConstant.Z_CZS_CY.equals(role) || SystemRoleConstant.Z_CZS_SZ.equals(role)) {
            areaIds = user.findUserManageTownId();
        } else if (SystemRoleConstant.SQ.equals(role)) {
            areaIds = user.findUserManageCommunityId();
        } else if (SystemRoleConstant.JU_WEI.equals(role)) {
            areaIds = user.findUserManageJuWeiId();
        } else {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
        }

        String agree = checkCurrentStatusStr(1, role);
        String audit = checkCurrentStatusStr(2, role);
        String refuse = checkCurrentStatusStr(3, role);
        String draft = checkCurrentStatusStr(4, role);
        flag = reportFormsMapper.findReportFormsSize(user.getId(), areaIds, reportType, agree, audit, refuse, draft);
        return flag;


    }

    /**
     * 操作凭证
     *
     * @param uploadVoucherReq 参数
     */
    @Override
    public void uploadVoucher(UploadVoucherReq uploadVoucherReq) throws SzException {
        uploadVoucherReq.format();

        AxhFinanceVo flag = reportFormsMapper.findReportFormById(uploadVoucherReq.getId());
        if (null == flag) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有查询到数据");
        }

        if (!OneLevelAuditConstant.DRAFT.equals(flag.getCurrentStatus())) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "审核中~~~");
        }

        DtUsersVo user = DtUsersVo.findCurrentUser();
        if (!flag.getCreateUserId().equals(user.getId())) {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
        }

        reportFormsMapper.uploadVoucher(uploadVoucherReq);
    }

    /**
     * 通过前端的参数判断需要查询的报表状态
     *
     * @param currentStatus
     * @param role
     * @return
     * @throws SzException
     */
    private String checkCurrentStatusStr(Integer currentStatus, Integer role) throws SzException {
        if (null == currentStatus) {
            return null;
        }
        if (SystemRoleConstant.CUN.equals(role) || SystemRoleConstant.SQ.equals(role) || SystemRoleConstant.JU_WEI.equals(role)) {
            if (currentStatus.equals(0)) {
                return null;
            } else if (currentStatus.equals(1)) {
                return TwoLevelAuditConstant.TWO_CONSENT + "";
            } else if (currentStatus.equals(2)) {
                return TwoLevelAuditConstant.SUBMIT_AUDIT + "," + TwoLevelAuditConstant.ONE_CONSENT + "," + TwoLevelAuditConstant.TWO_FAIL;
            } else if (currentStatus.equals(3)) {
                return TwoLevelAuditConstant.ONE_FAIL + "";
            } else if (currentStatus.equals(4)) {
                return TwoLevelAuditConstant.DRAFT + "";
            }
        } else if (SystemRoleConstant.Z_CZS_CY.equals(role) || SystemRoleConstant.Z_CZS_SZ.equals(role)) {
            if (currentStatus.equals(0)) {
                return null;
            } else if (currentStatus.equals(1)) {
                return OneLevelAuditConstant.CONSENT + "";
            } else if (currentStatus.equals(2)) {
                return OneLevelAuditConstant.SUBMIT_AUDIT + "";
            } else if (currentStatus.equals(3)) {
                return OneLevelAuditConstant.FAIL + "";
            } else if (currentStatus.equals(4)) {
                return OneLevelAuditConstant.DRAFT + "";
            }
        } else {
            throw new SzException(SystemCode.QUERY_CHECK_ERROR, "没有操作权限~~~");
        }

        return null;
    }

    /**
     * 判断报表是否允许删除
     *
     * @param financeVo 报表
     */
    private Boolean checkIsAllowDeleteReportForm(AxhFinanceVo financeVo, DtUsersVo user) {
        //不是本人的报表
        if (!user.getId().equals(financeVo.getCreateUserId())) {
            return Boolean.FALSE;
        }

        if (!OneLevelAuditConstant.DRAFT.equals(financeVo.getCurrentStatus())) {
            return Boolean.FALSE;
        }


        return Boolean.TRUE;
    }

    /**
     * 查询地区类型
     *
     * @param role 角色
     * @return 类型
     */
    private Integer findAreaType(Integer role) {
        Integer areaType = -1;
        //镇财政所成员
        if (SystemRoleConstant.Z_CZS_CY.equals(role)) {
            areaType = AddressConstant.ZJ;
        }
        //居委会、社区
        else if (SystemRoleConstant.SQ.equals(role)) {
            areaType = AddressConstant.SQ;
        }
        //村
        else if (SystemRoleConstant.CUN.equals(role)) {
            areaType = AddressConstant.CUN;
        } else if (SystemRoleConstant.JU_WEI.equals(role)) {
            areaType = AddressConstant.JW;
        }
        return areaType;
    }
}
